/*
 * $Id: StringUtil.java,v 1.2 2005/01/31 05:27:54 jdon Exp $
 *
 *  Copyright (c) 2001, 2002 The Open For Business Project - www.ofbiz.org
 *
 *  Permission is hereby granted, free of charge, to any person obtaining a
 *  copy of this software and associated documentation files (the "Software"),
 *  to deal in the Software without restriction, including without limitation
 *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
 *  and/or sell copies of the Software, and to permit persons to whom the
 *  Software is furnished to do so, subject to the following conditions:
 *
 *  The above copyright notice and this permission notice shall be included
 *  in all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 *  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 *  CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
 *  OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
 *  THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

package org.eduapp.trains.utils;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringReader;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 *
 * @author  Brian Chan
 * @version $Revision: 1.2 $
 *
 */
public class UtilsString {
	
  public static final String allChar = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  public static final String letterChar = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  public static final String numberChar = "0123456789";
  public static final char[] upperChar = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
  
  public static String generateString(int length) 
  {
   StringBuffer sb = new StringBuffer();
   Random random = new Random();
   for (int i = 0; i < length; i++)
   {
    sb.append(allChar.charAt(random.nextInt(allChar.length())));
   }
  return sb.toString();
  }
  
  public static boolean contains(String s, String text, String delimiter) {
    if ( (s == null) || (text == null) || (delimiter == null)) {
      return false;
    }

    if (!s.endsWith(delimiter)) {
      s += delimiter;
    }

    int pos = s.indexOf(delimiter + text + delimiter);

    if (pos == -1) {
      if (s.startsWith(text + delimiter)) {
        return true;
      }

      return false;
    }

    return true;
  }

  public static int count(String s, String text) {
    if ( (s == null) || (text == null)) {
      return 0;
    }

    int count = 0;

    int pos = s.indexOf(text);

    while (pos != -1) {
      pos = s.indexOf(text, pos + text.length());
      count++;
    }

    return count;
  }

  public static String merge(String array[], String delimiter) {
    if (array == null) {
      return null;
    }

    StringBuffer sb = new StringBuffer();

    for (int i = 0; i < array.length; i++) {
      sb.append(array[i].trim());

      if ( (i + 1) != array.length) {
        sb.append(delimiter);
      }
    }

    return sb.toString();
  }

  public static String read(ClassLoader classLoader, String name) throws
      IOException {

    return read(classLoader.getResourceAsStream(name));
  }

  public static String read(InputStream is) throws IOException {
    BufferedReader br = new BufferedReader(new InputStreamReader(is));

    StringBuffer sb = new StringBuffer();
    String line = null;

    while ( (line = br.readLine()) != null) {
      sb.append(line).append('\n');
    }

    br.close();

    return sb.toString().trim();
  }

  public static String remove(String s, String remove, String delimiter) {
    if ( (s == null) || (remove == null) || (delimiter == null)) {
      return null;
    }

    if (UtilsValidate.isNotEmpty(s) && !s.endsWith(delimiter)) {
      s += delimiter;
    }

    while (contains(s, remove, delimiter)) {
      int pos = s.indexOf(delimiter + remove + delimiter);

      if (pos == -1) {
        if (s.startsWith(remove + delimiter)) {
          s = s.substring(
              remove.length() + delimiter.length(), s.length());
        }
      } else {
        s = s.substring(0, pos) + s.substring(pos + remove.length() +
                                              delimiter.length(), s.length());
      }
    }

    return s;
  }

  public static String replace(String s, String oldSub, String newSub) {
    if ( (s == null) || (oldSub == null) || (newSub == null)) {
      return null;
    }

    int y = s.indexOf(oldSub);

    if (y >= 0) {
      StringBuffer sb = new StringBuffer();
      int length = oldSub.length();
      int x = 0;

      while (x <= y) {
        sb.append(s.substring(x, y));
        sb.append(newSub);
        x = y + length;
        y = s.indexOf(oldSub, x);
      }

      sb.append(s.substring(x));

      return sb.toString();
    } else {
      return s;
    }
  }

  public static String replace(String s, String[] oldSubs, String[] newSubs) {
    if ( (s == null) || (oldSubs == null) || (newSubs == null)) {
      return null;
    }

    if (oldSubs.length != newSubs.length) {
      return s;
    }

    for (int i = 0; i < oldSubs.length; i++) {
      s = replace(s, oldSubs[i], newSubs[i]);
    }

    return s;
  }

  public static String reverse(String s) {
    if (s == null) {
      return null;
    }

    char[] c = s.toCharArray();
    char[] reverse = new char[c.length];

    for (int i = 0; i < c.length; i++) {
      reverse[i] = c[c.length - i - 1];
    }

    return new String(reverse);
  }

  public static String shorten(String s) {
    return shorten(s, 20);
  }

  public static String shorten(String s, int length) {
    return shorten(s, length, "..");
  }

  public static String shorten(String s, String suffix) {
    return shorten(s, 20, suffix);
  }

  public static String shorten(String s, int length, String suffix) {
    if (s == null || suffix == null) {
      return null;
    }

    if (s.length() > length) {
      s = s.substring(0, length) + suffix;
    }

    return s;
  }

  public static String[] split(String s, String delimiter) {
    if (s == null || delimiter == null) {
      return new String[0];
    }

    if (!s.endsWith(delimiter)) {
      s += delimiter;
    }

    s = s.trim();

    if (s.equals(delimiter)) {
      return new String[0];
    }

    List<String> nodeValues = new ArrayList<String>();

    if (delimiter.equals("\n") || delimiter.equals("\r")) {
      try {
        BufferedReader br = new BufferedReader(new StringReader(s));

        String line = null;

        while ( (line = br.readLine()) != null) {
          nodeValues.add(line);
        }

        br.close();
      } catch (IOException ioe) {
        ioe.printStackTrace();
      }
    } else {
      int offset = 0;
      int pos = s.indexOf(delimiter, offset);

      while (pos != -1) {
        nodeValues.add(s.substring(offset, pos));

        offset = pos + delimiter.length();
        pos = s.indexOf(delimiter, offset);
      }
    }

    return (String[]) nodeValues.toArray(new String[0]);
  }

  public static boolean[] split(String s, String delimiter, boolean x) {
    String[] array = split(s, delimiter);
    boolean[] newArray = new boolean[array.length];

    for (int i = 0; i < array.length; i++) {
      boolean value = x;

      try {
        value = Boolean.valueOf(array[i]).booleanValue();
      } catch (Exception e) {
      }

      newArray[i] = value;
    }

    return newArray;
  }

  public static double[] split(String s, String delimiter, double x) {
    String[] array = split(s, delimiter);
    double[] newArray = new double[array.length];

    for (int i = 0; i < array.length; i++) {
      double value = x;

      try {
        value = Double.parseDouble(array[i]);
      } catch (Exception e) {
      }

      newArray[i] = value;
    }

    return newArray;
  }

  public static float[] split(String s, String delimiter, float x) {
    String[] array = split(s, delimiter);
    float[] newArray = new float[array.length];

    for (int i = 0; i < array.length; i++) {
      float value = x;

      try {
        value = Float.parseFloat(array[i]);
      } catch (Exception e) {
      }

      newArray[i] = value;
    }

    return newArray;
  }

  public static int[] split(String s, String delimiter, int x) {
    String[] array = split(s, delimiter);
    int[] newArray = new int[array.length];

    for (int i = 0; i < array.length; i++) {
      int value = x;

      try {
        value = Integer.parseInt(array[i]);
      } catch (Exception e) {
      }

      newArray[i] = value;
    }

    return newArray;
  }

  public static long[] split(String s, String delimiter, long x) {
    String[] array = split(s, delimiter);
    long[] newArray = new long[array.length];

    for (int i = 0; i < array.length; i++) {
      long value = x;

      try {
        value = Long.parseLong(array[i]);
      } catch (Exception e) {
      }

      newArray[i] = value;
    }

    return newArray;
  }

  public static short[] split(String s, String delimiter, short x) {
    String[] array = split(s, delimiter);
    short[] newArray = new short[array.length];

    for (int i = 0; i < array.length; i++) {
      short value = x;

      try {
        value = Short.parseShort(array[i]);
      } catch (Exception e) {
      }

      newArray[i] = value;
    }

    return newArray;
  }

  public static final String stackTrace(Throwable t) {
    String s = null;

    try {
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      t.printStackTrace(new PrintWriter(baos, true));
      s = baos.toString();
    } catch (Exception e) {
    }

    return s;
  }

  public static boolean startsWith(String s, char begin) {
    return startsWith(s, (new Character(begin)).toString());
  }

  public static boolean startsWith(String s, String begin) {
    if ( (s == null) || (begin == null)) {
      return false;
    }

    if (begin.length() > s.length()) {
      return false;
    }

    String temp = s.substring(0, begin.length());

    if (temp.equalsIgnoreCase(begin)) {
      return true;
    } else {
      return false;
    }
  }

  public static String wrap(String text) {
    return wrap(text, 80);
  }

  public static String wrap(String text, int width) {
    if (text == null) {
      return null;
    }

    StringBuffer sb = new StringBuffer();

    try {
      BufferedReader br = new BufferedReader(new StringReader(text));

      String s = "";

      while ( (s = br.readLine()) != null) {
        if (s.length() == 0) {
          sb.append("\n");
        } else {
          while (true) {
            int pos = s.lastIndexOf(' ', width);

            if ( (pos == -1) && (s.length() > width)) {
              sb.append(s.substring(0, width));
              sb.append("\n");

              s = s.substring(width, s.length()).trim();
            } else if ( (pos != -1) && (s.length() > width)) {
              sb.append(s.substring(0, pos));
              sb.append("\n");

              s = s.substring(pos, s.length()).trim();
            } else {
              sb.append(s);
              sb.append("\n");

              break;
            }
          }
        }
      }
    } catch (IOException ioe) {
      ioe.printStackTrace();
    }

    return sb.toString();
  }

  public static String getPassword(int length, String key) {

    StringBuffer sb = new StringBuffer();

    for (int i = 0; i < length; i++) {
      sb.append(key.charAt( (int) (Math.random() * key.length())));
    }

    return sb.toString();
  }

  public static String getPassword(int length) {
    String key =
        "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    return getPassword(length, key);
  }

  /**
   * Encode a string using algorithm specified in web.xml and return the
   * resulting encrypted password. If exception, the plain credentials
   * string is returned
   *
   * @param password Password or other credentials to use in authenticating
   *        this username
   * @param algorithm Algorithm used to do the digest
   *
   * @return encypted password based on the algorithm.
   */
  public static String encodePassword(String password, String algorithm) {
    byte[] unencodedPassword = password.getBytes();

    MessageDigest md = null;

    try {
      // first create an instance, given the provider
      md = MessageDigest.getInstance(algorithm);
    } catch (Exception e) {
      System.err.print("Exception: " + e);

      return password;
    }

    md.reset();

    // call the update method one or more times
    // (useful when you don't know the size of your data, eg. stream)
    md.update(unencodedPassword);

    // now calculate the hash
    byte[] encodedPassword = md.digest();

    StringBuffer buf = new StringBuffer();

    for (int i = 0; i < encodedPassword.length; i++) {
      if ( ( (int) encodedPassword[i] & 0xff) < 0x10) {
        buf.append("0");
      }

      buf.append(Long.toString( (int) encodedPassword[i] & 0xff, 16));
    }

    return buf.toString();
  }

  /**
   * Encode a string using Base64 encoding. Used when storing passwords
   * as cookies.
   *
   * This is weak encoding in that anyone can use the decodeString
   * routine to reverse the encoding.
   *
   * @param str
   * @return String
   */
  public static String encodeString(String str) {
    return UtilsBase64.encodeBytes((str.getBytes())).trim();
  }

  /**
   * Decode a string using Base64 encoding.
   *
   * @param str
   * @return String
   */
  public static String decodeString(String str) {
    try {
      return new String(UtilsBase64.decode(str));
    } catch (IOException io) {
      throw new RuntimeException(io.getMessage(), io.getCause());
    }
  }
  
  public static String cutString(int len, String str) {
	if (str == null) {
		return "";
	}
	str = str.trim();
	if (str.length() < len) {
		return str;
	}
	return str.substring(0, len) + "...";
  }

  public static boolean isEmpty(Object obj) {
	return obj == null || obj.toString().trim().length() == 0;
  }
  
  public static boolean isNotEmpty(Object obj){
	return !isEmpty(obj);
  }
  
  public static String toUTF8String(String s, String charset){
      StringBuffer sb = new StringBuffer();
        for (int i=0;i<s.length();i++){
           char c = s.charAt(i);
           if (c >= 0 && c <= 255){sb.append(c);}
         else{
         byte[] b;
          try { b = Character.toString(c).getBytes(charset);}
          catch (Exception ex) {
              System.out.println(ex);
                   b = new byte[0];
          }
             for (int j = 0; j < b.length; j++) {
              int k = b[j];
               if (k < 0) k += 256;
               sb.append("%" + Integer.toHexString(k).toUpperCase());
               }
      }
   }
   return sb.toString();
  }
  
}
